package general;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.OWLAnnotation;
import org.semanticweb.owlapi.model.OWLAnnotationProperty;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObject;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.vocab.OWLRDFVocabulary;

import componentManager.Terme;

import queryManager.QrelManager;
import queryManager.QrelOutputManager;
import queryManager.Query;
import queryManager.QueryParser;
import queryManager.Requete;
import queryManager.SemanticQuery;
import utils.BDD;


public class EvaluatorSemantic {

	public static final String DOCUMENT_IRI = "balade.owl";
	public static OWLAnnotationProperty label;
	public static OWLOntology ont;
	
	public static HashMap<String, OWLObject> search;
	//precision for each request
	private HashMap<Integer,ArrayList<Double>> datas ;
	
	public EvaluatorSemantic() throws IOException, OWLOntologyCreationException, ClassNotFoundException, InstantiationException, IllegalAccessException{
		search = new HashMap<String, OWLObject>();
		init();
		search.putAll(fill_class_labels(ont,label));
//		search.putAll(fill_individual_labels(ont,label));
//		afficherHashMap(search);
		datas = new HashMap<Integer, ArrayList<Double>>();
		evaluate();
	}
	
	
	public void init() throws OWLOntologyCreationException{
		// Create our manager
		OWLOntologyManager man = OWLManager.createOWLOntologyManager();

		// Load the ontology
		ont = man.loadOntologyFromOntologyDocument(new File(DOCUMENT_IRI));
//		System.out.println("Loaded: " + ont.getOntologyID());

		OWLDataFactory df = man.getOWLDataFactory();

		// Firstly, get the annotation property for rdfs:label
		label = df.getOWLAnnotationProperty(OWLRDFVocabulary.RDFS_LABEL
						.getIRI());
	}
	
	public void evaluate() throws IOException, OWLOntologyCreationException, ClassNotFoundException, InstantiationException, IllegalAccessException {
		
		BDD.getInstance();
		
		//on traite toutes les requetes et on stocke les resultats dans des fichiers
		SemanticQuery req = null;
		for(Query q : IHM.queries){
			req = new SemanticQuery(q,search,"sortiesSemantic");
			req.getRequete().printInFile();
		}
		
		//on recupere nos resultats
		QrelOutputManager qrelOutputManager = new QrelOutputManager("sortiesSemantic","^qrel[0-9]+\\.txt$");
		HashMap<Integer,ArrayList<String>> queryOutputResults = qrelOutputManager.getQrels();
		
		//on calcule les precisions
		for(int id : IHM.queryResults.keySet()){
			double a = Evaluator.precision(queryOutputResults.get(id),IHM.queryResults.get(id),5)/5;
			double b = Evaluator.precision(queryOutputResults.get(id),IHM.queryResults.get(id),10)/10;
			double c = Evaluator.precision(queryOutputResults.get(id),IHM.queryResults.get(id),25)/25;
			ArrayList<Double> l = new ArrayList<Double>();
			l.add(a);l.add(b);l.add(c);
			datas.put(id, l);
			
		}

	}
	
	//filling in the hashtable containing labels of instances and its value
	//<annotation individu, value>
	public static HashMap<String, OWLObject>  fill_individual_labels (OWLOntology ont,OWLAnnotationProperty label) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
		HashMap<String, OWLObject> search = new HashMap<String, OWLObject>();
		 //Gets the individuals that are in the signature of this ontology. 
	    for (OWLNamedIndividual ind : ont.getIndividualsInSignature()) {
	 	// Get the annotations on the class that use the label property
	        for (OWLAnnotation annotation : ind.getAnnotations(ont, label)) {
	            if (annotation.getValue() instanceof OWLLiteral) {
	                OWLLiteral val = (OWLLiteral) annotation.getValue();
	                for(String s : Requete.initKeyWords(val.getLiteral(), new Double(0)).keySet()){
	                	if(!search.containsKey(s)){
	                		search.put(s, ind);
//	                		System.out.println("---------------------"+s+"///"+ind);
	                	}
	                	
	                }
//	                search.put(Terme.lemmatise(val.getLiteral()), ind);
	                
	            }
	        }
	    }
	    return search;
    }
		 
	 //<annotation class,value>
	 public static HashMap<String, OWLObject>  fill_class_labels (OWLOntology ont,OWLAnnotationProperty label) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
		 HashMap<String, OWLObject> search = new HashMap<String, OWLObject>();
		 // on parcours toutes les classes de l'ontologie
	 	for (OWLClass cls : ont.getClassesInSignature()) {
	 		if(!cls.toString().equals("owl:Thing")){
//		 		System.out.println("*****************"+cls.toString());
		 	// Get the annotations on the class that use the label property
		            for (OWLAnnotation annotation : cls.getAnnotations(ont, label)) {
		                if (annotation.getValue() instanceof OWLLiteral) {
		                    OWLLiteral val = (OWLLiteral) annotation.getValue();
		                    //stockage dans HashMap    
		                    for(String s : Requete.initKeyWords(val.getLiteral(), new Double(0)).keySet()){
		                    	if(!search.containsKey(s)){
		                    		search.put(s, cls);
//		                    		System.out.println("---------------------"+s+"///"+cls);
		                    	}
			                }
	//	                    search.put(Terme.lemmatise(val.getLiteral()), cls);
		                }
		            }
	            
	            
		            for (OWLIndividual o : cls.getIndividuals(ont)) {
						for (OWLAnnotation annotation : o.asOWLNamedIndividual()
								.getAnnotations(ont)) {
							 if (annotation.getValue() instanceof OWLLiteral) {
								OWLLiteral val = (OWLLiteral) annotation.getValue();
								// stockage des labels dans le hashmap
								for(String s : Requete.initKeyWords(val.getLiteral(), new Double(0)).keySet()){
			                    	if(!search.containsKey(s)){
			                    		search.put(s, o);
//			                    		System.out.println("++++++++++++++++"+s+"///"+o);
			                    	}
				                }
							}					
						 }
					}
	            
	 		}
	 	}
	 	return search;
    }
		 
	 /**
	  * affichage du contenu de l'HashMap
	  * @param search
	 */
	public void afficherHashMap(HashMap<String, OWLObject> search) {
		for (Iterator<String> it = search.keySet().iterator(); it.hasNext();) {
			String key = it.next();
			System.out.println(key + " -> " + search.get(key));
		}
	}

	public HashMap<Integer, ArrayList<Double>> getDatas() {
		return datas;
	}

	public void setDatas(HashMap<Integer, ArrayList<Double>> datas) {
		this.datas = datas;
	}
	
	
}
